/*****************************************************************************
 * Included Files
 ****************************************************************************/

#include "log.h"
#include <stdarg.h>
#include "stdio.h"
#include "string.h"


/*****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/
 
#define		LOG_LEVEL_TAG_INFO		"I"
#define		LOG_LEVEL_TAG_WARN		"W"
#define		LOG_LEVEL_TAG_ERROR		"E"
#define		LOG_LEVEL_TAG_DEBUG		"D"

/*****************************************************************************
 * Private Types
 ****************************************************************************/

/*****************************************************************************
 * Private Function Prototypes
 ****************************************************************************/


/*****************************************************************************
 * Public Data
 ****************************************************************************/

/*****************************************************************************
 * Private Functions
 ****************************************************************************/

/*****************************************************************************
 * Private Data
 ****************************************************************************/

static const char *log_leveltag(int level)
{
	const char *tag = "";
	
	switch(level){
		case LOG_LEVEL_INFO:
			tag = LOG_LEVEL_TAG_INFO; 
			break; 
		case LOG_LEVEL_WARN:
			tag = LOG_LEVEL_TAG_WARN; 
			break; 
		case LOG_LEVEL_ERROR:
			tag = LOG_LEVEL_TAG_ERROR; 
			break; 
		case LOG_LEVEL_DEBUG:
			tag = LOG_LEVEL_TAG_DEBUG; 
			break; 
		default:
			tag = "#UNK";
			break; 
	}

	return (tag);
}

static const char *log_filename(const char *filename)
{
    size_t i, start;

    for (start = 0, i = strlen(filename); i > 0; i--) {
        /* Only for windows IAR */
        if (filename[i - 1] == '\\') {
            start = i;
            break;
        } else if (filename[i - 1] == '/') {
            start = i;
            break;
        }
    }

    return (filename + start);
}

static 	int log_print(const char *fmt,...)
{
	int 	rc;

	va_list ap; 
	va_start(ap,fmt); 
	rc = vprintf(fmt,ap);
	va_end(ap);
	
	return (rc);
}


static void log_header_print(int level,
								const char *file,
								const int line)
{
	log_print("[%s]",log_leveltag(level)); 
	log_print("[%-18.18s/%04d] : ",log_filename(file),line); 
}

								
/*****************************************************************************
 * Public Function Prototypes
 ****************************************************************************/

/**
 *
 *log格式：[I][file	/ line]: message
 *
 */
void log_message(int         level,
					 const char * file,
					 const int 	line,
                     const char *fmt,
                      ...)
{
	log_header_print(level,file,line);
	
	/* message */
	 char	 buffer[LOG_MESSAGE_MAXLEN];
	
    va_list ap;		

    va_start(ap, fmt);		
    (void)vsnprintf(buffer, sizeof(buffer), fmt, ap);
    va_end(ap);

	printf("%s \r\n",buffer);
}


void log_hexdecimal(int level,
					const char *location,
					int line,
					const char *prefix,
					const void *ptr,
					int size)
{
	log_header_print(level,location,line);

	log_print("%s(%d)\r\n",prefix,size);

	int offset = 0; 
	char *data = (char *)ptr; 
	while(offset < size){
		log_print(" %02xH",data[offset++]);

		if(offset%16 == 0)
			log_print(" \r\n");
	}

	log_print("\r\n");
}

					  

